package br.com.bancodecurriculos.pessoa.fisica.gui;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.MaskFormatter;

import br.com.bancodecurriculos.pessoa.comum.dominio.Endereco;
import br.com.bancodecurriculos.pessoa.comum.dominio.Endereco.TipoEndereco;
import br.com.bancodecurriculos.pessoa.fisica.negocio.PessoaFisicaServices;

public class EnderecoForm extends JDialog {

	private static final long serialVersionUID = 1L;

	private static final String LOGRADOURO = "Logradouro *";
	private static final String NUMERO = "Número *";
	private static final String COMPLEMENTO = "Complmento";
	private static final String BAIRRO = "Bairro *";
	private static final String CEP = "CEP *";
	private static final String CIDADE = "Cidade";
	private static final String UF = "UF";
	private static final String TIPO = "Tipo *";
	private static final String ADICIONAR = "Adicionar";
	private static final String REMOVER = "Remover";
	private static final String SALVAR = "Salvar";

	private static final String[] ESTADOS = new String[] { "AC", "AL", "AP",
			"AM", "BA", "CE", "DF", "ES", "GO", "MA", "MT", "MS", "MG", "PA",
			"PB", "PR", "PE", "PI", "RJ", "RN", "RS", "RO", "RR", "SC", "SP",
			"SE", "TO" };

	private static final String MASCARA_CEP = "#####-###";

	private static final String ENDERECO_NAO_ENCONTRADO = "Endereço não encontrado!";
	private static final String ENDERECO_EXISTENTE = "Endereço já existe!";
	private final String CAMPOS_INVALIDOS = "Campos inválidos!";
	private final String VAZIO = "";

	private final Font FONT = new Font("Microsoft Sans Serif", Font.PLAIN, 14);

	private JLabel lblLogradouro;
	private JLabel lblNmero;
	private JLabel lblComplemento;
	private JLabel lblBairro;
	private JLabel lblCep;
	private JLabel lblCidade;
	private JLabel lblUf;
	private JLabel lblTipo;
	private JTextField txtFLogradouro;
	private JTextField txtFNumero;
	private JTextField txtFComplemento;
	private JTextField txtFBairro;
	private JTextField txtCidade;
	private JFormattedTextField frmtdtxtfldCep;
	private JComboBox<String> cmbbxUf;
	private JComboBox<String> cmbbxTipo;
	private JButton btnAdicionar;
	private JButton btnRemover;
	private JButton btnSalvar;
	private JScrollPane scrollPane;
	private DefaultTableModel defaultTableModel;
	private JTable table;

	private List<Endereco> enderecos;

	public EnderecoForm() {
		super();
		this.enderecos = new ArrayList<Endereco>();
		init();
	}

	private void init() {
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		this.setBounds(100, 100, 425, 462);
		this.getContentPane().setLayout(null);
		try {
			this.initComponentes();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		this.setResizable(false);
		this.carregarCmbbxUf();
		this.carregarTipoEndereco();
		this.acoes();
		this.setLocationRelativeTo(null);
	}

	private void initComponentes() throws ParseException {
		this.lblLogradouro = new JLabel(LOGRADOURO);
		this.lblLogradouro.setFont(FONT);
		this.lblLogradouro.setBounds(12, 12, 99, 15);
		this.getContentPane().add(this.lblLogradouro);

		this.txtFLogradouro = new JTextField();
		this.txtFLogradouro.setFont(FONT);
		this.txtFLogradouro.setBounds(129, 10, 283, 20);
		this.getContentPane().add(this.txtFLogradouro);
		this.txtFLogradouro.setColumns(10);

		this.lblNmero = new JLabel(NUMERO);
		this.lblNmero.setFont(FONT);
		this.lblNmero.setBounds(12, 39, 99, 15);
		this.getContentPane().add(this.lblNmero);

		this.txtFNumero = new JTextField();
		this.txtFNumero.setFont(FONT);
		this.txtFNumero.setBounds(129, 37, 114, 20);
		this.getContentPane().add(this.txtFNumero);
		this.txtFNumero.setColumns(10);

		this.lblComplemento = new JLabel(COMPLEMENTO);
		this.lblComplemento.setFont(FONT);
		this.lblComplemento.setBounds(12, 66, 99, 15);
		this.getContentPane().add(this.lblComplemento);

		this.txtFComplemento = new JTextField();
		this.txtFComplemento.setFont(FONT);
		this.txtFComplemento.setBounds(129, 64, 114, 20);
		this.getContentPane().add(this.txtFComplemento);
		this.txtFComplemento.setColumns(10);

		this.lblBairro = new JLabel(BAIRRO);
		this.lblBairro.setFont(FONT);
		this.lblBairro.setBounds(12, 93, 99, 15);
		this.getContentPane().add(this.lblBairro);

		this.txtFBairro = new JTextField();
		this.txtFBairro.setFont(FONT);
		this.txtFBairro.setBounds(129, 91, 282, 20);
		this.getContentPane().add(this.txtFBairro);
		this.txtFBairro.setColumns(10);

		this.lblCep = new JLabel(CEP);
		this.lblCep.setFont(FONT);
		this.lblCep.setBounds(12, 120, 99, 15);
		this.getContentPane().add(this.lblCep);

		this.frmtdtxtfldCep = new JFormattedTextField(new MaskFormatter(
				MASCARA_CEP));
		this.frmtdtxtfldCep.setFont(FONT);
		this.frmtdtxtfldCep.setBounds(129, 118, 114, 20);
		this.getContentPane().add(this.frmtdtxtfldCep);

		this.lblCidade = new JLabel(CIDADE);
		this.lblCidade.setFont(FONT);
		this.lblCidade.setBounds(12, 147, 99, 15);
		this.getContentPane().add(this.lblCidade);

		this.txtCidade = new JTextField();
		this.txtCidade.setBounds(129, 145, 282, 20);
		this.getContentPane().add(this.txtCidade);
		this.txtCidade.setColumns(10);

		this.lblUf = new JLabel(UF);
		this.lblUf.setFont(FONT);
		this.lblUf.setBounds(12, 174, 99, 15);
		this.getContentPane().add(this.lblUf);

		this.cmbbxUf = new JComboBox<String>();
		this.cmbbxUf.setFont(FONT);
		this.cmbbxUf.setBounds(129, 171, 57, 20);
		this.getContentPane().add(this.cmbbxUf);

		this.lblTipo = new JLabel(TIPO);
		this.lblTipo.setFont(FONT);
		this.lblTipo.setBounds(12, 201, 70, 15);
		getContentPane().add(lblTipo);

		this.cmbbxTipo = new JComboBox<String>();
		this.setFont(FONT);
		this.cmbbxTipo.setBounds(129, 196, 144, 20);
		this.getContentPane().add(this.cmbbxTipo);

		this.btnAdicionar = new JButton(ADICIONAR);
		this.btnAdicionar.setFont(FONT);
		this.btnAdicionar.setBounds(86, 228, 117, 25);
		this.getContentPane().add(btnAdicionar);

		this.btnRemover = new JButton(REMOVER);
		this.btnRemover.setFont(FONT);
		this.btnRemover.setBounds(215, 228, 117, 25);
		this.getContentPane().add(this.btnRemover);

		this.scrollPane = new JScrollPane();
		this.scrollPane.setBounds(12, 265, 399, 120);
		this.getContentPane().add(this.scrollPane);

		this.defaultTableModel = new DefaultTableModel();
		this.defaultTableModel.addColumn(LOGRADOURO);
		this.defaultTableModel.addColumn(NUMERO);
		this.defaultTableModel.addColumn(COMPLEMENTO);
		this.defaultTableModel.addColumn(BAIRRO);
		this.defaultTableModel.addColumn(CEP);
		this.defaultTableModel.addColumn(CIDADE);
		this.defaultTableModel.addColumn(UF);

		this.table = new JTable(this.defaultTableModel);
		this.scrollPane.setViewportView(this.table);

		this.btnSalvar = new JButton(SALVAR);
		this.btnSalvar.setFont(FONT);
		this.btnSalvar.setBounds(151, 396, 117, 25);
		this.getContentPane().add(this.btnSalvar);
	}

	private void carregarCmbbxUf() {
		for (String uf : ESTADOS) {
			this.cmbbxUf.addItem(uf);
		}
	}

	private void carregarTipoEndereco() {
		try {
			List<TipoEndereco> tipoEnderecos = PessoaFisicaServices
					.getInstance().getAllTipoEnderecos();
			for (TipoEndereco tipo : tipoEnderecos) {
				this.cmbbxTipo.addItem(tipo.getNome());
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void acoes() {
		this.btnAdicionar.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if (validarCampos()) {
					Endereco endereco = criarEndereco();
					// ERRADO
					if (!enderecos.contains(endereco)) {
						adicionar(endereco);
					} else {
						JOptionPane.showMessageDialog(EnderecoForm.this,
								ENDERECO_EXISTENTE, ADICIONAR,
								JOptionPane.ERROR_MESSAGE);
					}
				} else {
					JOptionPane.showMessageDialog(EnderecoForm.this,
							CAMPOS_INVALIDOS, ADICIONAR,
							JOptionPane.ERROR_MESSAGE);
				}
			}
		});

		this.btnRemover.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if (validarCampos()) {
					Endereco endereco = criarEndereco();
					if (enderecos.contains(endereco)) {
						remover(endereco);
					} else {
						JOptionPane.showMessageDialog(EnderecoForm.this,
								ENDERECO_NAO_ENCONTRADO, REMOVER,
								JOptionPane.ERROR_MESSAGE);
					}
				} else {
					JOptionPane.showMessageDialog(EnderecoForm.this,
							CAMPOS_INVALIDOS, REMOVER,
							JOptionPane.ERROR_MESSAGE);
				}
			}
		});

		this.btnSalvar.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				dispose();
			}
		});
	}

	private Endereco criarEndereco() {
		String logradouro = txtFLogradouro.getText();
		int numero = Integer.parseInt(txtFNumero.getText());
		String complemento = txtFComplemento.getText();
		String bairro = txtFBairro.getText();
		String cep = frmtdtxtfldCep.getText();
		String cidade = txtCidade.getText();
		String uf = cmbbxUf.getSelectedItem().toString();
		String tipo = cmbbxTipo.getSelectedItem().toString();
		try {
			TipoEndereco tipoEndereco = PessoaFisicaServices.getInstance()
					.getTipoEnderecoByNome(tipo);
			return new Endereco(logradouro, numero, complemento, cep, bairro,
					cidade, uf, tipoEndereco);
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		} catch (SQLException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		return null;
	}

	private boolean validarCampos() {
		if (this.txtFLogradouro.getText() == null
				|| VAZIO.equals(this.txtFLogradouro.getText())) {
			return false;
		} else if (this.txtFNumero.getText() == null
				|| VAZIO.equals(this.txtFNumero.getText())) {
			return false;
		} else if (this.txtFBairro.getText() == null
				|| VAZIO.equals(this.txtFBairro.getText())) {
			return false;
		} else if (this.frmtdtxtfldCep.getText() == null
				|| VAZIO.equals(this.frmtdtxtfldCep.getText())) {
			return false;
		}
		return true;
	}

	private void adicionar(Endereco endereco) {
		this.enderecos.add(endereco);
		this.carregarTabela(this.enderecos);
	}

	private void remover(Endereco endereco) {
		this.enderecos.remove(endereco);
		this.carregarTabela(this.enderecos);
	}

	private void carregarTabela(List<Endereco> enderecos) {
		this.defaultTableModel.setRowCount(0);
		for (Endereco endereco : enderecos) {
			this.defaultTableModel.addRow(new Object[] {
					endereco.getLogradouro(), endereco.getNumero(),
					endereco.getComplemento(), endereco.getBairro(),
					endereco.getCep(), endereco.getCidade(), endereco.getUf(),
					endereco.getTipoEndereco().getNome() });
		}
	}

	public List<Endereco> showDialog() {
		this.setVisible(true);
		return this.enderecos;
	}

}
